<?php

namespace App\Services;

use App\Models\Active;
use App\Models\ActiveRecord;
use App\Models\MoneyDeposit;
use App\Models\MoneyWithdraw;
use App\Models\Order;
use App\Models\Setting;
use App\Models\UserLevel;
use App\Models\UserProperty;
use App\Models\WithdrawAuditListRecord;
use App\Models\WithdrawAuditRecord;
use App\User;
use common\enum\ActiveEnum;
use common\enum\CommonEnum;
use common\enum\MoneyDepositEnum;
use common\enum\MoneyWithdrawEnum;
use common\utils\SysCode;
use function foo\func;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;

/**
 * 稽核计算service
 * Class WithdrawAuditService
 * @package services
 */
class WithdrawAuditService
{
    // 优惠打码量要求类型 0 ：无 1： 倍数 2：总数量
    const ACTIVE_WITHDRAW_TYPE_NOTHING = 0;
    const ACTIVE_WITHDRAW_TYPE_TIMES = 1;
    const ACTIVE_WITHDRAW_TYPE_AMOUNT = 2;

    // 活动优惠发放状态  0：未发放，1：已经发放，2：超出发放数量，3：权限不足，不能发放
    const ACTIVE_STATUS_NO_SEND = 0;
    const ACTIVE_STATUS_SEND = 1; //已发放
    const ACTIVE_STATUS_OUT_NUMBER = 2;
    const ACTIVE_STATUS_NO_RIGHT = 3;
    const ACTIVE_STATUS_RETURN_BACK = 4; //冲销


    // =======注单状态======================================
    // 等待
    const ORDER_STATUS_WAITING = 0;
    // 接受
    const ORDER_STATUS_PENDING = 1;
    // 结算
    const ORDER_STATUS_OPEN = 2;
    // 取消
    const ORDER_STATUS_CANCEL = 3;
    //拒绝
    const ORDER_STATUS_REJECT = 4;

    // 流水倍数放大值
    const VALIDBET_MULTI_TIMES = 100;
    // 行政费的比例放大值
    const WITHDRAW_EXPENESE_RATE_TIMES = 10000;

    /**
     * 获取稽核数据  稽核入口
     *      如果该会员存在未结算的出款记录，则以出款方式计算稽核 提款额度按照提交的申请的额度
     *      否则以当前时间为计算稽核的时间  提款额度按照当前账户的余额
     *
     * 2018-11-27 稽核起始时间计算 规则
     *  如果用户有提过款，提款时间起始为上次提款申请时间，这个时间到免稽核时间段数据需要展示，稽核费用全是免稽核
     *  如果用户有没有提过款，提款时间起始为注册时间，这个时间到免稽核时间段数据需要展示，稽核费用全是免稽核
     *
     * @param int $userId 会员id
     * @param int $hallId 厅id
     * @param int $money 账户余额
     * @return array
     */
    public static function getWithdrawAuditInfo($userId, $hallId, $money = 0)
    {
        $user = User::where(['id' => $userId, 'hall_id' => $hallId])->first();
        if (empty($user)) {
            error_exit(SysCode::USER_NOT_FOUND);
        }
        $redis = Redis::connection();
        $redisValue = 1;
        $expiredTime = 1;
        $key = "withdraw_audit_out_user_" . $userId;
        if ($redis->get($key)) {
            error_exit(SysCode::FAILED, "请勿重复操作");
        }
        //设置并发KEY
        if (!$redis->set($key, $redisValue, 'nx', 'ex', $expiredTime)) {
            error_exit(SysCode::FAILED, "请勿重复操作");
        }
        // 获取当前时间
        $nowDate = date('Y-m-d H:i:s');
        $dateEnd = $nowDate;
        $orderDate = $nowDate;
        // 是否提交了提款申请
        $isApply = CommonEnum::DISABLE;
        //上一次完成提现的订单号
        $orderNumber = '';
        //当前未处理或者待支付的提现订单号
        $isApplyOrderNumber = '';
        // 出款扣除手续费
        $serviceFee = '';
        // 扣除行政费
        $adminFee = '';
        // 扣除优惠费用
        $couponFee = '';
        // 手续费修改前
        $serviceFeeBefore = 0;
        //行政费修改前
        $adminFeeBefore = 0;
        //优惠修改前
        $couponFeeBefore = 0;

        // 如果该会员存在未结算的出款记录，则以出款方式计算稽核 提款额度按照提交的申请的额度
        //待处理、待支付的提现
        //去除手动减少余额类型
        $withdrawData = MoneyWithdraw::where(['user_id' => $userId, 'hall_id' => $hallId])
            ->where('status', '<', MoneyWithdrawEnum::WITHDRAW_STATUS_PAID)
            ->where('type', '<=', MoneyWithdrawEnum::WITHDRAW_TYPE_MANUAL)
            ->orderBy('id', 'desc')
            ->first();
        //查找提现次数(成功、待处理、待支付的提现订单)
        $withdrawCount = MoneyWithdraw::where(['user_id' => $userId, 'hall_id' => $hallId])
            ->where('status', '<=', MoneyWithdrawEnum::WITHDRAW_STATUS_PAID)
            ->where('type', '<=', MoneyWithdrawEnum::WITHDRAW_TYPE_MANUAL)
            ->count();

        if (!empty($withdrawData)) {
            $isApply = CommonEnum::ENABLED;
            $isApplyOrderNumber = $withdrawData['order_number'];
            $orderNumber = $isApplyOrderNumber;
            $orderDate = $withdrawData->created_at->format("Y-m-d H:i:s");
            $dateEnd = $orderDate;
            // 如果该会员存在未结算的出款记录  计算稽核需要以当时层级和稽核数据展示
            $userLevel = !empty($withdrawData['level_config']) ? json_decode($withdrawData['level_config'], true) : [];
            $serviceFee = $withdrawData['fee'];
            $adminFee = $withdrawData['admin_fee'];
            $couponFee = $withdrawData['coupon_amount'];
            $serviceFeeBefore = $withdrawData['fee_before'];
            $adminFeeBefore = $withdrawData['admin_fee_before'];
            $couponFeeBefore = $withdrawData['coupon_amount_before'];
            $amount = $withdrawData['amount'];//提款金额
        } else {
            $amount = $money;//即时稽查询以当前余额为准
            // 获取层级配置信息
            $userLevel = UserLevel::where(['id' => $user['level_id'], 'hall_id' => $hallId])->first();
        }
        if (empty($userLevel)) {
            error_exit(SysCode::FAILED, "会员层级配置为空");
        }
        // 获取上次成功提款信息
        $withdrawData = MoneyWithdraw::where(['user_id' => $userId, 'hall_id' => $hallId, 'status' => MoneyWithdrawEnum::WITHDRAW_STATUS_PAID])->where('type', '<=', MoneyWithdrawEnum::WITHDRAW_TYPE_MANUAL)->orderBy('id', 'desc')->first();
        $dateBegin = null;
        if (!empty($withdrawData)) {
            $dateBegin = $withdrawData->created_at->format("Y-m-d H:i:s");
            if (!$isApply) {
                $orderNumber = $withdrawData['order_number'];
                $orderDate = $dateBegin;
            }
        } else {
            // 没有提过款，开始时间使用注册时间
            $dateBegin = $user->created_at->format("Y-m-d H:i:s");
        }

        // 获取免稽核时间(把当前的提现开始时间与免稽核时间作比较)
        $noCheckDate = self::getLastAuditDate($userId, $hallId, $dateBegin);

        //初始化数据
        $data = [
            'total_withdraw_validbet' => 0,
            'total_validbet' => 0,
            'total_admin_fee' => 0,
            'total_coupon' => 0,
            'service_fee' => 0,
            'day_withdraw_times' => 0,
            'list' => [],
        ];

        if (!$isApply) {
            // 获取即时稽核查询信息列表
            $data = self::getAuditDataList($userId, $hallId, $userLevel, $dateBegin, $dateEnd, $noCheckDate);
        } else {
            //有提款订单的时候，从稽核历史存储表中拿取(最新稽核计算)
            $result = WithdrawAuditRecord::where(['user_id' => $userId, 'order_number' => $isApplyOrderNumber])->first();
            if ($result) {
                $data = $result->toArray();
                $data['total_withdraw_validbet'] = $data['withdraw_validbet'];//打码量汇总
                $data['total_validbet'] = $data['validbet'];//有效投注汇总
                $data['total_admin_fee'] = $data['admin_fee'];//需扣除的总行政费
                $data['total_coupon'] = $data['coupon_fee'];//需扣除的总优惠
                $list = WithdrawAuditListRecord::where(['user_id' => $userId, 'order_number' => $isApplyOrderNumber])->get()->toArray();
                if (!empty($list)) {
                    foreach ($list as &$value) {
                        $value['date'] = $value['bet_time'];
                        $value['start_date'] = $value['begin_time'];
                        $value['end_date'] = $value['end_time'];
                        $value['betdetail'] = json_decode($value['bet_detail'], true);
                        unset($value['bet_detail']);
                    }
                }
                $data['list'] = $list;
                //当日提款次数
                $todayTimes = self::getWithdrawTimes($userId, $hallId);
                $data['day_withdraw_times'] = $todayTimes;
            }
        }

        $serviceFee = $serviceFee == '' ? $data['service_fee'] : $serviceFee;
        $adminFee = $adminFee == '' ? $data['total_admin_fee'] : $adminFee;
        $couponFee = $couponFee == '' ? $data['total_coupon'] : $couponFee;
        $totalFee = $serviceFee + $couponFee + $adminFee;
        $result = [
            'withdraw_min_limit' => $userLevel['withdraw_min_limit'],// 提款最小限制
            'withdraw_max_limit' => $userLevel['withdraw_max_limit'],// 提款最大限制
            'withdraw_daily_times_limit' => $userLevel['withdraw_daily_times_limit'],//每日出款次数限制
            'day_withdraw_times' => $data['day_withdraw_times'],//当天已提现次数
            'withdraw_daily_times_nofee_limit' => $userLevel['withdraw_daily_times_nofee_limit'],//每日免手续费次数
            'withdraw_expenese_rate' => $userLevel['withdraw_expenese_rate'],// 提现行政费比例
            'withdraw_expenese_max_limit' => $userLevel['withdraw_expenese_max_limit'],// 提现行政费上限
            'withdraw_fee' => $userLevel['withdraw_fee'],// 层级设定 提现手续费
            'nocheck_amount' => $userLevel['nocheck_amount'],//层级设定 免稽核额度
            'balance' => (int)$money,// 钱包余额
            'withdraw_amount' => (int)$amount,// 预提款金额
            'withdraw_count' => $withdrawCount,// 提款的次数
            'is_apply' => $isApply,// 是否有申请提款  0 没有  1有
            'order_number' => $orderNumber,// 申请提款/上次提款 的订单号
            'apply_time' => $orderDate,// 申请提款/上次提款 的时间
            'check_time' => $dateBegin,// 稽核开始时间
            'end_date' => $dateEnd,// 稽核截止时间
            'no_check_time' => $noCheckDate,// 最后免稽核时间
            'coupon_fee' => $couponFee,// 需扣除的总优惠
            'admin_fee' => $adminFee,// 需扣除的总行政费
            'service_fee' => $serviceFee,// 需扣除的手续费
            'total_fee' => $totalFee, // 总扣除的费用
            'coupon_fee_diff' => $isApply ? $couponFee - $couponFeeBefore : 0,// 修改的优惠额度  正数 增加  负数  减少
            'admin_fee_diff' => $isApply ? $adminFee - $adminFeeBefore : 0,// 修改的行政费额度
            'service_fee_diff' => $isApply ? $serviceFee - $serviceFeeBefore : 0,// 修改的手续费额度
            'coupon_fee_before' => $couponFeeBefore,// 修改前的优惠额度
            'admin_fee_before' => $adminFeeBefore,// 修改前的行政费额度
            'service_fee_before' => $serviceFeeBefore,// 修改前的优惠费额度
            'is_coupon_pass' => $couponFee > 0 ? 0 : 1,// 总优惠是否通过  0  未通过  1  通过
            'is_principal_pass' => $adminFee > 0 ? 0 : 1,// 总常态是否通过 0  未通过  1  通过
            'withdraw_validbet' => $data['total_withdraw_validbet'], // 打码量汇总
            'validbet' => $data['total_validbet'], // 有效投注汇总
            'list' => $data['list']// 稽核详细
        ];
        return $result;
    }

    /**
     * 获取上次稽核时间
     * @param int $userId 会员id
     * @param int $hallId 上次提款时间
     * @param string $lastWithdrawDate 上次提款时间
     * @return string
     */
    public static function getLastAuditDate($userId, $hallId, $lastWithdrawDate)
    {
        // 获取免稽核时间点
        $userProperty = UserProperty::where(['user_id' => $userId, 'hall_id' => $hallId])->first();
        if (!empty($userProperty) && !empty($userProperty->nocheck_time)) {
            $noCheckTime = $userProperty->nocheck_time->format("Y-m-d H:i:s");
            $noCheckTime > $lastWithdrawDate && $lastWithdrawDate = $noCheckTime;
        }
        return $lastWithdrawDate;
    }

    /**
     * 获取稽核数据列表
     * @param int $userId 会员id
     * @param int $hallId 厅id
     * @param string $dataBegin 起始时间
     * @param string $dataEnd 结束时间
     * @return array
     */
    public static function getAuditDataList($userId, $hallId, $userLevel, $dataBegin, $dataEnd, $noCheckDate)
    {
        $result = [
            'list' => [], //稽核列表
            'service_fee' => 0,// 手续费
            'total_admin_fee' => 0,// 扣除总行政费
            'total_coupon' => 0,// 扣除总优惠金额
        ];
        // 手续费计算 如果取款则需要计算，否则为0 兼容即时稽核
        $withdrawServiceFee = 0;
        // 今天提现次数是否在免手续费次数之内，否则需要计算
        $todayTimes = self::getWithdrawTimes($userId, $hallId);
        if ($todayTimes > $userLevel['withdraw_daily_times_nofee_limit']) {
            $withdrawServiceFee = $userLevel['withdraw_fee'];
        }
        // 手续费
        $result['service_fee'] = $withdrawServiceFee;
        $auditDataList = [];
        // 获取存款稽核信息  除了 手动补派奖金 和 手动扣回奖金  充值优惠是否和充值活动优惠不重复，一个是后台添加，一个是前端会员充值申请的
        $select = [
            'amount',
            'coupon_amount as coupon',
            'user_id',
            'recharge_time as date',
            'withdraw_validbet',
            'is_online',
            'coupon_validbet',
            'offline_pay_type'
        ];
        $depositList = MoneyDeposit::select($select)
            ->where([
                ['user_id', '=', $userId],
                ['hall_id', '=', $hallId],
                ['status', '=', MoneyDepositEnum::STATUS_PAID],
                ['created_at', '>=', $dataBegin],
                ['created_at', '<', $dataEnd],
            ])
            ->where(function ($q) {
                $q->orwhere('is_online', '=', MoneyDepositEnum::IS_ONLINE_TRUE)->orwhere(function ($q2) {
                    $q2->wherein('offline_pay_type', MoneyDepositEnum::DEPOST_TYPE_WITHDRAW_AUDIT);
                });
            })
            ->orderBy('recharge_time', 'desc')->get()->toArray();

        if (!empty($depositList)) {
            $auditDataList = array_merge($auditDataList, $depositList);
        }
        // 活动列表包括返水
        $activeRecordList = ActiveRecord::select([
            'active_record.amount as coupon',
            'active_record.user_id',
            'active_record.created_at as date',
            'active_record.withdraw_require as coupon_validbet',
        ])->where([
            ['user_id', '=', $userId],
            ['hall_id', '=', $hallId],
            ['updated_at', '>=', $dataBegin],
            ['updated_at', '<', $dataEnd]
        ])
            ->whereIn('status', [self::ACTIVE_STATUS_SEND])
            ->where('template_id', '<>', ActiveEnum::ACTIVE_RECHARGE_OFFER)
            ->where('amount', '>', 0)
            ->orderBy('created_at', 'desc')->get()->toArray();
        if (!empty($activeRecordList)) {
            $auditDataList = array_merge($auditDataList, $activeRecordList);
        }
        //按照时间顺序重新排序数组
        array_multisort(array_column($auditDataList, 'date'), SORT_DESC, $auditDataList);
        // 扣除行政费总和
        $totalAdminFee = 0;
        // 扣除优惠费总和
        $totalCoupon = 0;
        //打码量汇总
        $totalWithdrawValidbet = 0;
        //有效投注额汇总
        $totalValidbet = 0;
        if (!empty($auditDataList)) {
            // 获取所有时间段的投注记录
            $orderList = self::validOrders($userId, $hallId, $dataBegin, $dataEnd);
            $total = count($auditDataList);
            // 组装需要的数据
            foreach ($auditDataList as $idx => &$audit) {
                $audit['amount'] = empty($audit['amount']) ? 0 : $audit['amount'];
                // 获取时间段打码量之和
                $startDate = $audit['date'];
                $endDate = $idx == 0 ? $dataEnd : $auditDataList[$idx - 1]['date'];
                //计算每个时间段之间实际的打码量
                $valid = self::sumValidBet($startDate, $endDate, $orderList);
                $audit['validbet'] = $valid;
                // 各类游戏在该时间段内有效投注详情
                $betDetail = self::validBetDetail($startDate, $endDate, $orderList);
                $audit['betdetail'] = $betDetail;
                $audit['start_date'] = $startDate;
                $audit['end_date'] = $endDate;
                // 计算本次总打码量  本次总打码量 = 上次结余的打码量 + 本次的打码量
                $auditValid = ($idx == 0 ? 0 : $audit['overValid']) + $valid;
                // 获取单条数据的  常态打码量，优惠打码量，剩余打码量，行政费，优惠费
                $r = self::singleAudit($auditValid, $audit, $userLevel, $noCheckDate);
                $audit = array_merge($audit, $r);
                $totalAdminFee += empty($audit['admin_fee']) ? 0 : $audit['admin_fee'];//行政费汇总
                $totalCoupon += empty($audit['coupon_fee']) ? 0 : $audit['coupon_fee'];//优惠汇总
                $totalWithdrawValidbet += empty($audit['withdraw_validbet']) ? 0 : $audit['withdraw_validbet'];//打码量汇总
                $totalValidbet += empty($audit['validbet']) ? 0 : $audit['validbet'];//有效投注额汇总
                unset($audit['withdraw_validbet']);
                unset($audit['is_online']);
                unset($audit['coupon_validbet']);
                //本次稽核通过， 把剩余的打码量加到下次的稽核里
                if ($idx < $total - 1) {
                    $auditDataList[$idx + 1]['overValid'] = (empty($audit['left_validbet']) || $audit['left_validbet'] < 0) ? 0 : $audit['left_validbet'];
                }
            }
        }
        //稽核列表
        $result['list'] = empty($auditDataList) ? [] : $auditDataList;
        // 扣除总行政费
        $result['total_admin_fee'] = $totalAdminFee;
        // 扣除总优惠金额
        $result['total_coupon'] = $totalCoupon;
        //打码量汇总
        $result['total_withdraw_validbet'] = $totalWithdrawValidbet;
        //有效投注额汇总
        $result['total_validbet'] = $totalValidbet;
        //当天已提款次数
        $result['day_withdraw_times'] = $todayTimes;
        return $result;
    }

    // 获取今天是第几次提款
    private static function getWithdrawTimes($userId, $hallId)
    {
        $where = [
            ['user_id', '=', $userId],
            ['hall_id', '=', $hallId],
            ['status', '=', MoneyWithdrawEnum::WITHDRAW_STATUS_PAID],
            ['type', '<', MoneyWithdrawEnum::WITHDRAW_TYPE_MANUAL_DEDUCTED],
            ['created_at', '>=', date('Y-m-d 00:00:00')],
            ['created_at', '<=', date('Y-m-d 23:59:59')],
        ];
        $data = MoneyWithdraw::where($where)->count();
        return $data + 1;
    }

    /**
     * 获取对应有效投注金额
     * @param int $userId 会员id
     * @param int $hallId 厅id
     * @param string $dataBegin 起始时间
     * @param string $dataEnd 结束时间
     * @return array
     */
    private static function validOrders($userId, $hallId, $dataBegin, $dataEnd)
    {
        // 获取厅后台配置打码量计算比例
        $config = Setting::select('value')->where(['hall_id' => $hallId, 'key' => 'VALID_BET_PERCENT_SETTING'])->first();
        $settingConfig = $config['value'];
        $settingConfig = json_decode($settingConfig, true);
        if (empty($settingConfig)) {
            $settingConfig = [];
        }
        // 获取注单数据
        $whereBet = [
            ['reckon_time', '>=', $dataBegin],
            ['reckon_time', '<', $dataEnd],// 上限不加‘=’，避免一个注单算两次
            ['user_id', '=', $userId],
            ['hall_id', '=', $hallId],
            ['status', '=', self::ORDER_STATUS_OPEN],
        ];
        //稽核以注单结算时间为准2018-12-11更改（测试提出）
        $select = ['game_type as order_type', 'validbet as validbet', 'reckon_time as created', 'user_id'];
        $bet = Order::select($select)->where($whereBet)->get()->toArray();
        if (!empty($bet)) {
            foreach ($bet as &$order) {
                $field = '';
                switch ($order['order_type']) {
                    case CommonEnum::GAME_EGAME:
                        $field = 'game_egame';
                        break;
                    case CommonEnum::GAME_LIVE:
                        $field = 'game_live';
                        break;
                    case CommonEnum::GAME_SPORT:
                        $field = 'game_sport';
                        break;
                    case CommonEnum::GAME_ESPORT:
                        $field = 'game_esport';
                        break;
                    case CommonEnum::GAME_LOTTERY:
                        $field = 'game_lottery';
                        break;
                    case CommonEnum::GAME_CARD:
                        $field = 'game_card';
                        break;
                }
                $percent = isset($settingConfig[$field]) ? $settingConfig[$field] : CommonEnum::PERCENT_TIMES;
                // 获取有效投注相关数据  有效投注 * 稽核比例 = 完成的打码量
                $money = round($order['validbet'] * ($percent ? $percent : CommonEnum::PERCENT_TIMES) / CommonEnum::PERCENT_TIMES, 2);
                $order['validbet'] = $money;
            }
        } else {
            $bet = [];
        }
        return $bet;
    }

    /**
     * 获取有效投注详情
     * @param string $start_date 起始时间
     * @param string $end_date 结束时间
     * @param array $orders 注单信息
     * @return array
     */
    private static function validBetDetail($start_date, $end_date, $orders)
    {
        $data = [
            ['name' => '电子', 'validbet' => 0],
            ['name' => '视讯', 'validbet' => 0],
            ['name' => '体育', 'validbet' => 0],
            ['name' => '电竞', 'validbet' => 0],
            ['name' => '彩票', 'validbet' => 0],
            ['name' => '棋牌', 'validbet' => 0],
        ];
        if (!empty($orders)) {
            foreach ($orders as $order) {
                if ($order['created'] < $start_date || $order['created'] >= $end_date) {
                    continue;
                }
                $type = $order['order_type'];
                switch ($type) {
                    case CommonEnum::GAME_EGAME:
                        $data[0]['validbet'] += $order['validbet'];
                        break;
                    case CommonEnum::GAME_LIVE:
                        $data[1]['validbet'] += $order['validbet'];
                        break;
                    case CommonEnum::GAME_SPORT:
                        $data[2]['validbet'] += $order['validbet'];
                        break;
                    case CommonEnum::GAME_ESPORT:
                        $data[3]['validbet'] += $order['validbet'];
                        break;
                    case CommonEnum::GAME_LOTTERY:
                        $data[4]['validbet'] += $order['validbet'];
                        break;
                    case CommonEnum::GAME_CARD:
                        $data[5]['validbet'] += $order['validbet'];
                        break;
                    default:
                        break;
                }
            }
        }
        return $data;
    }

    /**
     * 获取时间段内的有效投注
     * @param string $start_date 起始时间
     * @param string $end_date 结束时间
     * @param array $orders 注单信息
     * @return float
     */
    private static function sumValidBet($start_date, $end_date, $orders)
    {
        $sum = 0;
        if (!empty($orders)) {
            foreach ($orders as $order) {
                if ($order['created'] < $start_date || $order['created'] >= $end_date) {
                    continue;
                }
                $sum += $order['validbet'];
            }
        }
        return round($sum, 0);
    }

    /**
     * 单条稽核数据的稽核以及费用计算  常态打码量，优惠打码量，剩余打码量，行政费，优惠费
     * 计算费用扣除情况方法：
     *      实际达到的打码量 =< 常态打码量 扣行政费
     *      实际达到的打码量 =< 优惠打码量 扣优惠
     * @param int $auditValid 有效投注
     * @param array $audit 单条稽核数据
     * @param array $userLevelConfig 用户层级设置
     * @return array
     */
    private static function singleAudit($auditValid, $audit, $userLevelConfig, $noCheckDate)
    {
        $isNoCheckData = false;
        if ($audit['date'] < $noCheckDate) {//等于免稽核时间也算
            $isNoCheckData = true;
        }
        $result = [
            'withdraw_bet_principal' => 0, // 常态打码量
            'withdraw_bet_coupon' => 0,// 优惠打码量
            'left_validbet' => 0,// 稽核转下次打码量
            'admin_fee' => 0,// 本次稽核行政费
            'coupon_fee' => 0,// 本次稽核优惠费
            'is_principal_pass' => 0,// 本次常态稽核是否通过  0  未通过  1  通过
            'is_coupon_pass' => 0,// 本次优惠稽核是否通过 0  未通过  1  通过
            'is_no_check' => (int)$isNoCheckData,//本次稽核是否为免稽核（免稽核则全部显示通过）
        ];
        // 存款计算稽核相关 充值记录一定有is_online的设置
        if (isset($audit['is_online'])) {
            // 获取常态打码量计算比例
            $rate = $audit['is_online'] ? $userLevelConfig['deposit_online_validbet_multi'] : $userLevelConfig['deposit_offline_validbet_multi'];
            // 获取常态打码量
            if (isset($audit['offline_pay_type'])
                && in_array($audit['offline_pay_type'],
                    [
                        MoneyDepositEnum::DEPOSIT_TYPE_MANUAL,
                        MoneyDepositEnum::DEPOSIT_TYPE_MANUAL_ADD,
                        MoneyDepositEnum::DEPOSIT_TYPE_MANUAL_COUPON,
                        MoneyDepositEnum::DEPOSIT_TYPE_MANUAL_REBATE,
                    ])
            ) {//人工存提， 填写的打码量 //手动存款， 手动增加余额， 手动返水 使用人工存提填写的打码量
                if ($audit['offline_pay_type'] == MoneyDepositEnum::DEPOSIT_TYPE_MANUAL) {
                    // 2018-12-04  手动存款 特殊处理 常态需要跟层级走
                    $withdraw_bet_principal = $audit['amount'] * $rate / self::VALIDBET_MULTI_TIMES;
                } else {
                    $withdraw_bet_principal = $audit['withdraw_validbet'];
                }
                $withdraw_bet_coupon = $audit['coupon_validbet'];
            } else {//一般类型
                //正常计算常态打码量
                $withdraw_bet_principal = $audit['amount'] * $rate / self::VALIDBET_MULTI_TIMES;
                // 获取优惠打码量
                $withdraw_bet_coupon = !empty($audit['coupon_validbet']) ? $audit['coupon_validbet'] : 0;
            }

            // 计算本次结余的打码量
            $leftAuditValid = $auditValid - max($withdraw_bet_principal, $withdraw_bet_coupon);
            // 行政费用
            $adminFee = $auditValid < $withdraw_bet_principal ? ($audit['amount'] * $userLevelConfig['withdraw_expenese_rate'] / self::WITHDRAW_EXPENESE_RATE_TIMES) : 0;
            $adminFee = min($adminFee, $userLevelConfig['withdraw_expenese_max_limit']);
            // 优惠费用
            $coupon = $auditValid < $withdraw_bet_coupon ? $audit['coupon'] : 0;
            $result['withdraw_bet_principal'] = $withdraw_bet_principal;
            $result['withdraw_bet_coupon'] = $withdraw_bet_coupon;
            $result['left_validbet'] = $leftAuditValid > 0 ? $leftAuditValid : 0;
            $result['admin_fee'] = $isNoCheckData ? 0 : $adminFee;
            $result['coupon_fee'] = $isNoCheckData ? 0 : $coupon;
            $result['is_principal_pass'] = $isNoCheckData ? 1 : ($auditValid >= $withdraw_bet_principal ? 1 : 0);
            $result['is_coupon_pass'] = $isNoCheckData ? 1 : ($auditValid >= $withdraw_bet_coupon ? 1 : 0);

        } else {
            // 优惠计算稽核相关
            // 获取常态打码量
            $withdraw_bet_principal = 0;
            // 获取优惠打码量
            $withdraw_bet_coupon = isset($audit['coupon_validbet']) ? $audit['coupon_validbet'] : 0;
            // 计算本次结余的打码量
            $leftAuditValid = $auditValid - $withdraw_bet_coupon;
            // 行政费用  没有存款没有行政费
            $adminFee = 0;
            // 优惠费用
            $coupon = $auditValid < $withdraw_bet_coupon ? $audit['coupon'] : 0;
            $result['withdraw_bet_principal'] = $withdraw_bet_principal;
            $result['withdraw_bet_coupon'] = $withdraw_bet_coupon;
            $result['left_validbet'] = $leftAuditValid > 0 ? $leftAuditValid : 0;
            $result['admin_fee'] = $isNoCheckData ? 0 : $adminFee;
            $result['coupon_fee'] = $isNoCheckData ? 0 : $coupon;
            $result['is_principal_pass'] = $isNoCheckData ? 1 : ($auditValid >= $withdraw_bet_principal ? 1 : 0);
            $result['is_coupon_pass'] = $isNoCheckData ? 1 : ($auditValid >= $withdraw_bet_coupon ? 1 : 0);
        }
        return $result;
    }
}